package web

import (
	"HomeMaterialManagementSystem/config"
	"HomeMaterialManagementSystem/db"
	"HomeMaterialManagementSystem/models"
	"HomeMaterialManagementSystem/web/controllers"
	"context"
	"log"
	"net/http"
	"path/filepath"

	"github.com/gin-contrib/multitemplate"

	"github.com/gin-gonic/gin"
)

type WebService struct {
	srv *http.Server
}

func init() {
	// gin.SetMode(gin.DebugMode)
}

func (web *WebService) Start() {
	bind, err := config.GetHTTPBind()
	if err != nil {
		bind = ":9980"
	}
	router := gin.Default()
	router.Static("/assets", "web/assets")
	router.StaticFile("/favicon.ico", "web/assets/images/icon-64.png")
	router.HTMLRender = loadTemplates("web/templates/")
	router.GET("/", index)

	controllers.BindRouters(router)

	web.srv = &http.Server{
		Addr:    bind,
		Handler: router,
	}

	go func() {
		// service connections
		if err := web.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen: %s\n", err)
		}
	}()
	log.Printf("Web service running at %s\n", bind)
}

func (web *WebService) Stop() {
	ctx := context.Background()
	if err := web.srv.Shutdown(ctx); err != nil {
		log.Fatal("HTTP Stop:", err)
	}
	// catching ctx.Done(). timeout of 5 seconds.
	// <-ctx.Done()
	// log.Println("HTTP Stop timeout of 5 seconds.")

}

func loadTemplates(templatesDir string) multitemplate.Renderer {
	r := multitemplate.NewRenderer()

	layouts, err := filepath.Glob(templatesDir + "/layouts/*.html")
	if err != nil {
		panic(err.Error())
	}

	includes, err := filepath.Glob(templatesDir + "/includes/*.html")
	if err != nil {
		panic(err.Error())
	}

	// Generate our templates map from our layouts/ and includes/ directories
	for _, include := range includes {
		layoutCopy := make([]string, len(layouts))
		copy(layoutCopy, layouts)
		files := append(layoutCopy, include)
		r.AddFromFiles(filepath.Base(include), files...)
	}
	return r
}

func index(c *gin.Context) {
	sessionText, err := c.Cookie("hmmssession")
	if err != nil {
		c.Redirect(http.StatusFound, "/login")
		return
	}
	session := models.Session{}
	r := db.GetORM().Where(&models.Session{SessionText: sessionText}).First(&session)
	if r.Error != nil {
		log.Printf("%+v\n", r.Error)
		c.Redirect(http.StatusFound, "/login")
		return
	}
	c.HTML(http.StatusOK, "index.html", gin.H{
		"username": session.User.Name,
		"title":    "主页",
	})
}
